<?php

namespace helper\baidu;

use helper\Client;
use helper\facade\IMap;

class Map implements IMap
{
    private string $host = 'http://api.map.baidu.com';

    private string $key;

    /**
     * @var Client
     */
    protected Client $client;

    public function __construct($config)
    {
        $this->key = $config['key'];
        $this->client = new Client();
    }

    /**
     * 1.地点搜索
     * Place API
     * 区域类型，提供城市内、矩形、圆形
     */
    function place_search()
    {
        ;
    }

    /**
     * 2.坐标转换
     * @ 其它图商坐标:$lat：纬度,$lng：经度
     * @return array 百度地图坐标
     */
    public function convert(string $latitude, string $longitude)
    {
        $url = $this->host . "/geoconv/v1/?coords=$longitude,$latitude&from=1&to=5&ak=$this->key";
        $res = file_get_contents($url);
        $arr = json_decode($res, true);
        $lng = $arr['locations']['lng'];//纬度
        $lat = $arr['locations']['lat'];//经度
        return array('lat' => $lat, 'lng' => $lng);
    }

    /**
     * 关键词输入提升
     * @param string $region 城市
     * @param string $keyword 关键词
     * @return mixed
     */
    public function getSuggestion(string $region, string $keyword)
    {
        $key = $this->key;
        $url = $this->host . "/place/v2/suggestion?query=$keyword&region=$region&output=json&ak=$key";
        $res = file_get_contents($url);
        $arr = json_decode($res, true);
        if ($arr['status'] == 0) {
            return $arr;
        } else {
            return $arr['message'];
        }
    }

    /**
     * 4.Geocoding API 是一类接口，用于提供从地址到经纬度坐标或者从经纬度坐标到地址的转换服务
     * 1) 逆地址解析
     * @param string $location 经纬度坐标
     * @return array
     */
    public function getAddress(string $location, string $batch = 'false'): array
    {
        $path = "/reverse_geocoding/v3/?ak=$this->key&output=json&coordtype=wgs84ll&location=$location";
        $response = $this->client->get($this->host . $path);
        $res = [];
        if ($response->getStatusCode() != 200) {
            return $res;
        }
        $body = $response->getBody();
        if ($body['status'] == 0) {
            return $body['result'];
        }
        return $res;

        $result = $this->request('GET', $url);
        if ($result['statusCode'] == 200 && isset($result['body']['status']) && $result['body']['status'] == 1) {
            return $result['body'];
        } else {
            return [];
        }
    }

    /**
     * 2) 地址解析:根据地理位置获得经纬度
     * @param string $address 位置
     * @return array
     */
    public function getLocation(string $address)
    {
        $key = $this->key;
        $url = $this->host . "/geocoding/v3/?ak=$key&output=json&address=$address";
        $res = file_get_contents($url);
        $arr = json_decode($res, true);
        //状态码
        // if ($arr['status'] == 0) {
        // 	$lng = $arr['result']['location']['lng'];//纬度
        // 	$lat = $arr['result']['location']['lat'];//经度
        // 	return array('lat'=>$lat,'lng'=>$lng);
        // }else{
        // 	return $arr['message'];//状态说明
        // }
        return $arr;
    }

    /**
     * 6.IP定位
     * @param string $ip
     * @return array 经纬度：lat、lng 地址：国家、省、市、行政区划代码
     */
    function ip_location($ip)
    {
        $key = $this->key;
        $url = $this->host . "/location/ip?ak=$key&coor=bd09ll";
        $res = file_get_contents($url);
        $arr = json_decode($res, true);
        if ($arr['status'] == 0) {
            $lat = $arr['content']['point']['y'];//纬度
            $lng = $arr['content']['point']['x'];//经度
            $city = $arr['content']['address_detail']['city'];//城市
            return array('lat' => $lat, 'lng' => $lng, 'city' => $city);
        }
    }

    /**
     * 8.路线规划距离和行驶时间
     * Route Matrix
     * driving（驾车）、riding（骑行）、walking（步行）
     * @return $distance 距离，单位：米
     * @return $duration 驾车时间，单位：默认秒转换成分钟
     */
    function route_matrix($lat1, $lng1, $lat2, $lng2, $mode = 'driving')
    {
        $location = $lat1 . "," . $lng1;
        $destination = $lat2 . "," . $lng2;
        $url = $this->host . "/routematrix/v2/$mode?output=json&origins=$location&destinations=$destination&ak={$this->key}";
        $res = file_get_contents($url);
        $arr = json_decode($res, true);
        if ($arr['status'] == 0) {
            $distance = $arr['result']['0']['distance']['text'];
            $duration = $arr['result']['0']['duration']['text'];
            return array('distance' => $distance, 'duration' => $duration);
        } else {
            return $arr['message'];
        }
    }

    /**
     * 国内天气
     * @param $district_id
     * @return array
     */
    public function weather($district_id): array
    {
        $path = "/weather/v1/?district_id={$district_id}&data_type=all&ak={$this->key}";
        $response = $this->client->get($this->host . $path);
        $res = [];
        if ($response->getStatusCode() != 200) {
            return $res;
        }
        $body = $response->getBody();
        if ($body['status'] == 0) {
            return $body['result'];
        }
        return $res;
    }

    /**
     * 发起请求 string $method, $uri = '', array $options = []
     * @param string $method
     * @param string $url
     * @param array $options
     * @return array
     */
    private function request(string $method, string $url, array $options = [])
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curl, CURLOPT_URL, $url);
        if (isset($options['headers'])) {
            curl_setopt($curl, CURLOPT_HTTPHEADER, $options['headers']);
        }
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, true);
        if (1 == strpos("$" . $url, "https://")) {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        }
        if (isset($options['json'])) {
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($options['json']));
        }

        $result = curl_exec($curl);
        $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
        $rheader = substr($result, 0, $header_size);
        $rbody = substr($result, $header_size);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        return [
            'statusCode' => $httpCode,
            'body' => json_decode($rbody, true)
        ];
    }
}
